package com.ww.java.generic.wildcard;

public class Holder<T> {

	private T value;
	
	public Holder() {}
	
	public Holder(T val) {
		value = val;
	}
	
	public void set(T val) {
		value = val;
	}
	
	public T get() {
		return value;
	}
	
	@Override
	public boolean equals(Object obj) {
		return value.equals(obj);
	}
	
	/**
	 * Holder有一个接受T类型对象的set()方法，一个get()方法，以及一个接受Object对象的equals()方法。
	 * 正如你已经看到的，如果创建了一个Holder<Apple>，不能将其向上转型为Holder<Fruit>，但是可以
	 * 将其向上转型为Holder<? extends Fruit>。如果调用get()，它只会返回一个Fruit。
	 * set()方法不能工作于Apple或Fruit，因为set()的参数也是"? extends Fruit"，这意味着它可以是任何
	 * 事务，而编译器无法验证“任何事物”的类型安全性。
	 * @param args
	 */
	@SuppressWarnings("unused")
	public static void main(String[] args) {
		Holder<Apple> apple = new Holder<>(new Apple());
		Apple d = apple.get();
		apple.set(d);
		
		// Type mismatch: cannot convert from Holder<Apple> to Holder<Fruit>
//		Holder<Fruit> fruit = apple;
		
		// 可以赋值
		Holder<? extends Fruit> fruit = apple;
		Fruit p = fruit.get();
		d = (Apple) fruit.get();
		
		try {
			Orange c = (Orange) fruit.get();
		} catch (Exception e) {
			// java.lang.ClassCastException: class com.ww.java.generic.wildcard.Apple cannot be cast to class com.ww.java.generic.wildcard.Orange 
			// (com.ww.java.generic.wildcard.Apple and com.ww.java.generic.wildcard.Orange are in unnamed module of loader 'app')
			System.out.println(e);
		}
		
		// The method set(capture#4-of ? extends Fruit) in the type Holder<capture#4-of ? extends Fruit> 
		// is not applicable for the arguments (Apple)
//		fruit.set(new Apple());
		
		System.out.println(fruit.equals(d));
	}
}
